package com.gcloud.mesh.analysis.ml;

import java.util.Arrays;

import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
import org.springframework.stereotype.Component;

import com.gcloud.mesh.analysis.data.IDataCleaning;
import com.gcloud.mesh.header.exception.AnalysisErrorCode;
import com.gcloud.mesh.header.exception.BaseException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class PolynomialModelFitter implements IFitter{
	
	public static String TYPE = "polynomial";
	
//	public static void main(String[] args) {
//		PolynomialModelFitter model = new PolynomialModelFitter();
//		PolynomialDataCleaning data = new PolynomialDataCleaning();
//		double[] result = model.train(data, 2);
//		System.out.println("here");
//	}
	
	public WeightedObservedPoints handleDatasets(IDataCleaning data) {
		WeightedObservedPoints points = new WeightedObservedPoints();
//		double[] x = new double[] {6, 8, 10, 114, 18};
//		double[] y = new double[] {7, 9, 13, 17.5, 18};
		double[] x = data.getX();
		double[] y = data.getY();
		for(int i=0; i<x.length; i++) {
			points.add(x[i], y[i]);
		}	
		return points;
	}
	
	public double[] train(IDataCleaning data, int degree) {
		double[] factors = new double[] {0, 0, 0, 0, 0 ,0};
		if(data == null || data.getData().size() == 0) {
			return factors;
		}
		WeightedObservedPoints points = new WeightedObservedPoints(); 
		points = handleDatasets(data);
		PolynomialCurveFitter fitter = PolynomialCurveFitter.create(degree);  // degree 指定多项式阶数 
//		double[] factors = new double[] {0, 0, 0, 0, 0 ,0};
		double[] result = fitter.fit(points.toList());
		for(int i=0; i<result.length; i++) {
			factors[i] = result[i];
		}
		return factors;
	}
	
	public IFitterOptimizer getOptimum(double[] factors, int degree) {
		IFitterOptimizer data = null;
		if(factors.length != 5 && Arrays.stream(factors).sum() == 0) {
			log.error("[PolynomialModelFitter][getOptimum] factors值不符合要求");
			throw new BaseException(AnalysisErrorCode.DATEBASE_DELETE_ERROR);
		}
		if(degree < 1 && degree > 5) {
			log.error("[PolynomialModelFitter][getOptimum] degree合理取值范围：0~5");
			throw new BaseException(AnalysisErrorCode.DATEBASE_DELETE_ERROR);
		}
		switch(degree) {
			case 1: break;
			case 2: data = new SecondOrderPolynomialOptimizer(factors);break;
			case 3: break;
			case 4: break;
			case 5: break;
		
		}
		return data;
	}
	
	public String getType() {
		return this.TYPE;
	}
	
}
